`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2022/04/21 20:17:35
// Design Name: 
// Module Name: AXI_R_Arbitor
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module AXI_R_Arbitor(
input logic clk,
input logic rst_n,
//
input logic m0_arvalid,
input logic m1_arvalid,
input logic m2_arvalid,
input logic m3_arvalid,
input logic m0_rvalid,
input logic m1_rvalid,
input logic m2_rvalid,
input logic m3_rvalid,
input logic m0_rready,
input logic m1_rready,
input logic m2_rready,
input logic m3_rready,
//
output logic [2:0] cur_master
    );
//
typedef enum {
   IDLE,
   MASTER0,
   MASTER1,
   MASTER2,
   MASTER3
}State;
//
logic end1;
logic end2;
logic end3;
logic end0;                    //只有end信号为高时才可进行下一次仲裁，否则表示上次获得总线控制权的主机还未传输完成
logic [3:0] master_req;
State next_state,state;
//master_req
assign master_req={m3_arvalid,m2_arvalid,m1_arvalid,m0_arvalid};
//stage1
always_ff@(posedge clk,negedge rst_n)
if(~rst_n)
    state<=IDLE;
else
    state<=next_state;
//stage2
always_comb
begin
   case(state)
       IDLE:if(rst_n)                            //此时优先级顺序为0>1>2>3
	         begin
			    if(master_req[0])
				    next_state=MASTER0;
				else if(master_req[1])
				    next_state=MASTER1;
				else if(master_req[2])
				    next_state=MASTER2;
				else if(master_req[3])
				    next_state=MASTER3;
				else 
				    next_state=IDLE;
			 end
			else
			   next_state=IDLE;
		MASTER0:begin
		        if(end0)                        //优先级1>2>3>0
				   if(master_req[1])
				       next_state=MASTER1;
				   else if(master_req[2])
				       next_state=MASTER2;
				   else if(master_req[3])
				       next_state=MASTER3;
				   else
				       next_state=MASTER0;
				else
				    next_state=MASTER0;
				end
		MASTER1:begin
		        if(end1)
				    if(master_req[2])
					   next_state=MASTER2;
					else if(master_req[3])
					   next_state=MASTER3;
					else if(master_req[0])
					   next_state=MASTER0;
					else 
					   next_state=MASTER1;
			    else
				    next_state=MASTER1;
				end
		MASTER2:begin
		        if(end2)
				    if(master_req[3])
					    next_state=MASTER3;
					else if(master_req[0])
					    next_state=MASTER0;
					else if(master_req[1])
					    next_state=MASTER1;
					else
					    next_state=MASTER2;
				else
				    next_state=MASTER2;
				end
		MASTER3:begin
		        if(end3)
				    if(master_req[0])
					    next_state=MASTER0;
					else if(master_req[1])
					    next_state=MASTER1;
					else if(master_req[2])
					    next_state=MASTER2;
					else
					    next_state=MASTER3;
				else
				    next_state=MASTER3;
				end
		default:next_state=IDLE;
	endcase    
end
//end0,end1,end2,end3
always_ff@(posedge clk,negedge rst_n)
if(~rst_n)
begin
    end0<=0;
    end1<=0;
	end2<=0;
	end3<=0;
end
else
case(state)
    MASTER0:if(m0_rvalid&&m0_rready)
	            end0<=1;
			else if(end0&&(|master_req))            //end为高且有主机请求
			    end0<=0;
	MASTER1:if(m1_rvalid&&m1_rready)
	            end1<=1;
			else if(end1&&(|master_req))
			    end1<=0;
	MASTER2:if(m2_rvalid&&m2_rready)
	            end2<=1;
			else if(end2&&(|master_req))
			    end2<=0;
	MASTER3:if(m3_rvalid&&m3_rready)
	            end3<=1;
			else if(end3&&(|master_req))
			    end3<=0;
endcase
//cur_master
always_comb
begin
case(state)
   MASTER0:cur_master=0;
   MASTER1:cur_master=1;
   MASTER2:cur_master=2;
   MASTER3:cur_master=3;
   default:cur_master=0;
endcase
end

endmodule
